#include	"ITank.h"
#include	<Math/Vector.h>
#include	<windows.h>
#include	<gl/gl.h>
#include	<gl/glu.h>

const float ITank::DEFAULT_SPEED = 1.5f;
const float ITank::SHOT_SPEED = 1.0f;
const float ITank::EPSILON = 0.0001f;

ITank::ITank()
	:	m_facing(up)
	,	m_pos(-1, -1)
	,	m_distance(0.0f)
	,	m_speed(DEFAULT_SPEED)
	,	m_lastShot(SHOT_SPEED * 2)
	,	m_map(0)
	,	m_shellList(0)
	,	m_color(1.0f, 0.5f, 1.0f, 1.0f)
	,	m_life(0)
{
}

void ITank::render() const
{
	if(m_pos != Vector2i(-1, -1))
	{
		Vector2f pos = m_pos;
		float angle = 0.0f;
		switch(m_facing)
		{
		case left:
			pos[0] -= m_distance;
			angle = 90.0f;
			break;
		case right:
			pos[0] += m_distance;
			angle = 270.0f;
			break;
		case up:
			pos[1] -= m_distance;
			angle = 0.0f;
			break;
		case down:
			pos[1] += m_distance;
			angle = 180.0f;
			break;
		}
		glMatrixMode(GL_MODELVIEW);
		glPushMatrix();
			glPushAttrib(GL_CURRENT_BIT  | GL_ENABLE_BIT);
				glDisable(GL_TEXTURE_2D);
				glDisable(GL_COLOR_MATERIAL);
				glDisable(GL_BLEND);
				glEnable(GL_DEPTH_TEST);
				glEnable(GL_CULL_FACE);
				Vector2f mapSize = m_map->getMapSize();
				glTranslatef(
					-mapSize[0] / 2 + 0.5f + pos[0],
					+mapSize[1] / 2 - 1.0f - pos[1],
					-m_map->getDepth() + 1.0f
					);
				glRotatef(angle, 0.0f, 0.0f, 1.0f);
				glBegin(GL_TRIANGLES);
					glNormal3f(0.0f, 0.0f, 1.0f);
					glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
					glVertex3f(-0.5f, -0.5f, 0.0f);
					glVertex3f( 0.5f, -0.5f, 0.0f);
					glColor4fv(m_color);
					glVertex3f( 0.0f,  0.5f, 0.0f);// */
				glEnd();

			glPopAttrib();
		glPopMatrix();
	}
}

void ITank::setShellList(ShellList * shellList)
{
	m_shellList = shellList;
}

void ITank::setMap(Map * map)
{
	m_map = map;
}

const Vector2i & ITank::getPos() const
{
	return m_pos;
}

void ITank::setPos(const Vector2i & pos)
{
	m_pos = pos;
}

bool ITank::isColliding(const Vector2f & pos) const
{
	Vector2f mpos = m_pos;
	switch(m_facing)
	{
	case left:
		mpos[0] -= m_distance;
		break;
	case right:
		mpos[0] += m_distance;
		break;
	case up:
		mpos[1] -= m_distance;
		break;
	case down:
		mpos[1] += m_distance;
		break;
	}
	mpos -= pos;
	return (mpos.LengthSquare() <= 0.25);
}

bool ITank::isDead() const
{
	return m_pos == Vector2i(-1, -1);
}

int ITank::getLife() const
{
	return m_life;
}

void ITank::setLife(int life)
{
	m_life = life;
}

void ITank::destroy()
{
	--m_life;
	m_distance = 0.0;
	return m_pos.Set(-1, -1);
}

bool ITank::checkWall(Facing facing) const
{
	Vector2i pos;
	pos = m_pos;
	switch(facing)
	{
	case left:
		pos[0] -= 1;
		break;
	case right:
		pos[0] += 1;
		break;
	case up:
		pos[1] -= 1;
		break;
	case down:
		pos[1] += 1;
		break;
	}
	if(m_map->isWall(pos))
	{
		return true;
	}
	else
	{
		return false;
	}
}

void ITank::shoot()
{
	if(m_lastShot >= ITank::SHOT_SPEED)
	{
		m_shellList->add(new Shell(m_map, m_facing, m_pos, m_distance, isPlayer()));
		m_lastShot = 0.0f;
	}
}

